<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
<script>
  // TODO: 题目
  // 1.this 的不同应用场景, 如何取值?
  // 2.手写bind函数
  // 3.实际开发中闭包的应用场景
  // 4.创建 10个 a 标签, 点击的时候弹出对应的序号
  
  let i, tag;
  for (i = 0; i < 10; i ++) {  // 将let 放到for里面形成一个块级作用域 或 ()()形式, 即可解决
    tag = document.createElement('a');
    tag.innerHTML = i + '<br />';
    tag.addEventListener('click', (e) => {
      e.preventDefault();
      alert(i);
    });
    document.body.appendChild(tag);
  }

  // TODO: 作用域: 某个变量的合法使用范围
    // 全局/函数/块级 作用域(let const 写的时候)

  // TODO: 自由变量: 一个变量在当前作用域没有定义, 但被使用了
    // 向上级作用域, 一层一层依次寻找, 直到找到为止, 如果到全局作用域都没找到, 则报错 xx is not defined

  // TODO: 闭包
    // 函数作为返回值被返回
    function create() {
      let a = 100;
      return function() {
        // a 是一个自由变量, 要在函数定义的地方，向上级作用域查找, 不是在执行的地方！！！
        console.log(a);
      }
    }
    let fn = create();
    let a = 200;
    fn();

    // 函数作为参数被传递
    function print(fn1) {
      let b = 200;
      fn1();
    }
    let b = 100;
    function fn1() {
      console.log(b);
    }
    print(fn1);

    // TODO: 闭包总结: https://juejin.cn/post/6844903940014735367
    // 当一个函数(outer)运行时它的形参或者它的私有变量(num,s)被内部函数(inner)所引用
    // 满足这个条件时, 那么这个outer就会形成闭包
    // 闭包 = outer函数 + 能够访问自由变量的inner函数

</script>
</body>
</html>